package cn.kevinkun.LeanCloud;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.Component;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;

import android.app.Activity;

@DesignerComponent(version = 20241014, category = ComponentCategory.EXTENSION, description = "http://www.kevinkun.cn/leancloud.html", iconName = "aiwebres/leancloud.svg", nonVisible = true)
@SimpleObject(external = true)
@UsesPermissions(permissionNames = "android.permission.INTERNET")
public class LeanUser extends AndroidNonvisibleComponent implements Component {

	public LeanUser(ComponentContainer container) {
		super(container.$form());
		activity = container.$context();
	}

	String url = "";
	String appid = "";
	String appkey = "";
	String token = "";
	String objectid = "";
	String username = "";
	String apiversion = "1.1";
	private final Activity activity;
	Map<String, String> headers = new HashMap<String, String>();

	@SimpleFunction(description = "")
	public void Init(String restApiUrl, String appId, String appKey) {
		url = restApiUrl;
		appid = appId;
		appkey = appKey;

		headers.clear();
		headers.put("X-LC-Id", appid);
		headers.put("X-LC-Key", appkey);
		headers.put("Content-Type", "application/json");
	}

	@SimpleFunction(description = "")
	public void Signup(final String userName, String password, String jsonData) {
		String realUrl = url + "/" + apiversion + "/users";

		if (jsonData.equals("")) {
			jsonData = "{}";
		}
		JSONObject jsonObject = null;
		try {
			jsonObject = new JSONObject(jsonData);
			jsonObject.put("username", userName);
			jsonObject.put("password", password);
		} catch (JSONException e1) {
			e1.printStackTrace();
		}

		byte[] body = jsonObject.toString().getBytes();
		HttpUtils.doHttpReqeust("POST", realUrl, headers, body, new HttpUtils.Callback() {

			@Override
			public void onSuccess(String result) {
				activity.runOnUiThread(new Runnable() {
					public void run() {
						JSONObject object;
						try {
							object = new JSONObject(result);
							if (object.has("error")) {
								OnError(object.getString("error"));
							} else {
								username = userName;
								token = object.getString("sessionToken");
								objectid = object.getString("objectId");
								String string = object.toString();
								SignedUp(string);
							}
						} catch (JSONException e) {
							OnError(e.getMessage());
						}

					}
				});
			}

			@Override
			public void onError(String error) {
				activity.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						OnError(error);
					}
				});
			}
		});

	}

	@SimpleFunction(description = "")
	public void Login(final String userName, String password) {

		String realUrl = url + "/" + apiversion + "/login";

		JSONObject data = new JSONObject();
		try {
			data.put("username", userName);
			data.put("password", password);
		} catch (JSONException e1) {
			e1.printStackTrace();
		}

		byte[] body = data.toString().getBytes();

		HttpUtils.doHttpReqeust("POST", realUrl, headers, body, new HttpUtils.Callback() {

			@Override
			public void onSuccess(String result) {
				activity.runOnUiThread(new Runnable() {
					public void run() {
						JSONObject object;
						try {
							object = new JSONObject(result);
							if (object.has("error")) {
								OnError(object.getString("error"));
							} else {
								username = userName;
								token = object.getString("sessionToken");
								objectid = object.getString("objectId");
								final String string = object.toString();
								LogedIn(string);
							}
						} catch (JSONException e) {
							OnError(e.getMessage());
						}
					}
				});
			}

			@Override
			public void onError(String error) {
				activity.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						OnError(error);
					}
				});
			}
		});

	}

	@SimpleFunction(description = "")
	public void UpdateProfile(String jsonData) {
		String realUrl = url + "/" + apiversion + "/users/" + objectid;

		byte[] body = jsonData.toString().getBytes();

		Map<String, String> headersWithSession = headers;
		headersWithSession.put("X-LC-Session", token);

		HttpUtils.doHttpReqeust("PUT", realUrl, headersWithSession, body, new HttpUtils.Callback() {

			@Override
			public void onSuccess(String result) {
				activity.runOnUiThread(new Runnable() {
					public void run() {
						JSONObject object;
						try {
							object = new JSONObject(result);
							if (object.has("error")) {
								OnError(object.getString("error"));
							} else {
								final String string = objectid.toString();
								UpdatedProfile(string);
							}
						} catch (JSONException e) {
							OnError(e.getMessage());
						}

					}
				});

			}

			@Override
			public void onError(String error) {
				activity.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						OnError(error);
					}
				});

			}
		});

	}

	@SimpleFunction(description = "")
	public void RequestEmailVerify(String email) {
		String realUrl = url + "/" + apiversion + "/requestEmailVerify";

		JSONObject data = new JSONObject();
		try {
			data.put("email", email);
		} catch (JSONException e1) {
			e1.printStackTrace();
		}
		byte[] body = data.toString().getBytes();
		HttpUtils.doHttpReqeust("POST", realUrl, headers, body, new HttpUtils.Callback() {

			@Override
			public void onSuccess(String result) {
				activity.runOnUiThread(new Runnable() {
					public void run() {
						JSONObject object;
						try {
							object = new JSONObject(result);
							if (object.has("error")) {
								OnError(object.getString("error"));
							} else {
								EmailVerified();
							}
						} catch (JSONException e) {
							e.printStackTrace();
						}

					}
				});
			}

			@Override
			public void onError(String error) {
				activity.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						OnError(error);
					}
				});
			}
		});

	}

	@SimpleFunction(description = "")
	public void RequestPasswordReset(String email) {
		String realUrl = url + "/" + apiversion + "/requestPasswordReset";

		JSONObject data = new JSONObject();
		try {
			data.put("email", email);
		} catch (JSONException e1) {
			e1.printStackTrace();
		}

		byte[] body = data.toString().getBytes();
		HttpUtils.doHttpReqeust("POST", realUrl, headers, body, new HttpUtils.Callback() {

			@Override
			public void onSuccess(String result) {
				activity.runOnUiThread(new Runnable() {
					public void run() {
						JSONObject object;
						try {
							object = new JSONObject(result);
							if (object.has("error")) {
								OnError(object.getString("error"));
							} else {
								PasswordReset();
							}
						} catch (JSONException e) {
							OnError("RequestPasswordReset error 3: " + e.getMessage());

						}

					}
				});

			}

			@Override
			public void onError(String error) {
				activity.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						OnError(error);
					}
				});

			}
		});

	}

	@SimpleFunction(description = "")
	public void UpdatePassword(String oldpassword, String newpassword) {
		String realUrl = url + "/" + apiversion + "/users/" + objectid + "/updatePassword";

		JSONObject data = new JSONObject();
		try {
			data.put("old_password", oldpassword);
			data.put("new_password", newpassword);
		} catch (JSONException e1) {
			e1.printStackTrace();
		}

		byte[] body = data.toString().getBytes();

		Map<String, String> headersWithSession = headers;
		headersWithSession.put("X-LC-Session", token);

		HttpUtils.doHttpReqeust("PUT", realUrl, headersWithSession, body, new HttpUtils.Callback() {

			@Override
			public void onSuccess(String result) {
				activity.runOnUiThread(new Runnable() {
					public void run() {
						JSONObject object;
						try {
							object = new JSONObject(result);
							if (object.has("error")) {
								OnError(object.getString("error"));
							} else {
								token = object.getString("sessionToken");
								UpdatedPassword();
							}
						} catch (JSONException e) {
							OnError(e.getMessage());
						}

					}
				});

			}

			@Override
			public void onError(String error) {
				activity.runOnUiThread(new Runnable() {
					@Override
					public void run() {
						OnError(error);
					}
				});

			}
		});

	}

	@SimpleProperty(description = "")
	public String SessionToken() {
		return token;
	}

	@SimpleProperty(description = "")
	public String UserId() {
		return objectid;
	}

	@SimpleProperty(description = "")
	public String Username() {
		return username;
	}

	@SimpleEvent
	public void OnError(String error) {
		EventDispatcher.dispatchEvent(this, "OnError", error);
	}

	@SimpleEvent
	public void SignedUp(String userinfo) {
		EventDispatcher.dispatchEvent(this, "SignedUp", userinfo);
	}

	@SimpleEvent
	public void LogedIn(String userinfo) {
		EventDispatcher.dispatchEvent(this, "LogedIn", userinfo);
	}

	@SimpleEvent
	public void UpdatedProfile(String userinfo) {
		EventDispatcher.dispatchEvent(this, "UpdatedProfile", userinfo);
	}

	@SimpleEvent
	public void EmailVerified() {
		EventDispatcher.dispatchEvent(this, "EmailVerified");
	}

	@SimpleEvent
	public void PasswordReset() {
		EventDispatcher.dispatchEvent(this, "PasswordReset");
	}

	@SimpleEvent
	public void UpdatedPassword() {
		EventDispatcher.dispatchEvent(this, "UpdatedPassword");
	}

}
